﻿using System.Text;

namespace TPXSDK.NET.Mission.Instruction;

internal class InstIOCtrl : Tokenizer
{
    public InstIOCtrl(TokenizerAdmin admin)
    {
        Admin = admin;
        KeyName = "ioctrl";
        KeyValue = (byte)FlyCmdId.CMD_IOCTRL;
        Usage = "ioctrl [set|reset|toggle] ch";
        Description = @"set/reset/toggle GPIO channel";
    }

    /// <inheritdoc />
    /// <summary>
    /// 词元分析器处理过程
    /// </summary>
    public override bool Process()
    {
        var flyCmp = Admin?.Compiler; if (null == flyCmp) return false;
        var tokens = flyCmp.GetLineTokens();

        if (null == tokens || tokens.Count != 3)
        {
            flyCmp.ErrorMsg = $"{KeyName} Invalid Usage";
            return false;
        }

        var cmd = new FlyCmdItem
        {
            Id = (byte)KeyValue,
            LineNum = tokens[0].Row
        };

        tokens.RemoveAt(0);// Remove Flycmd Name
        cmd.P1 = 0xFF;
        // 通道控制动作编码
        if (string.Equals(tokens[0].Name, "reset", StringComparison.OrdinalIgnoreCase)) cmd.P1 = 0;
        if (string.Equals(tokens[0].Name, "set", StringComparison.OrdinalIgnoreCase)) cmd.P1 = 1;
        if (string.Equals(tokens[0].Name, "toggle", StringComparison.OrdinalIgnoreCase)) cmd.P1 = 2;
        if (0xFF == cmd.P1)
        {
            flyCmp.ErrorMsg = $"{KeyName} Invalid param";
            return false;
        }
        // 通道编号处理
        if (tokens[1].Type != TokenType.NUMBER) return false;
        cmd.P2 = FlyUtils.ToInt16(tokens[1].Name);
        flyCmp.CmdList.Add(cmd);
        return true;
    }

    public override void Reverse(FlyCmdItem cmd, StringBuilder sb)
    {
        var p1 = "?";
        if (cmd.P1 == 0) p1 = "reset";
        if (cmd.P1 == 1) p1 = "set";
        if (cmd.P1 == 2) p1 = "toggle";
        sb.AppendLine($"{KeyName} {p1} {cmd.P2}");
    }
}
